/**
 * Copyright (C) 2015-2018 IQIYI
 * All rights reserved.
 *
 * Author     : 王海斌
 * E-mail     : wanghaibin@qiyi.com
 * Version    :
 * Date       : Mon 01 Jul 2019 10:34:43 AM CST
 * Destription: 测试vector的内存空间释放
 */

#include <iostream>
#include <vector>
#include <stdio.h>
#include <unistd.h>
using namespace std;

class Test1
{
public:
    Test1 (){ data_ = 0;}
    Test1 (int data) {
        data_ = data;
        printf("Call Construct.\r\n");

    }
    ~Test1 (){}
    Test1(const Test1 & x) {
        printf("Call Copy Construct.\r\n");
        *this = x;
    }
    Test1 &operator=(const Test1 & x) {
        printf("Call Copy Assign.\r\n");
        data_ = x.data_;
        return *this;
    }
    void PrintValue() {
        printf("cur valu=%d\n", data_);
    }
private:
    int data_;
};

void test_vector_copy()
{
    vector<Test1> vec;
    Test1 t2(20);
    Test1 *tmp = &t2;

    printf("\r\n\r\n");
    vec.push_back(t2);
    printf("after push t2\r\n");
    vec.push_back(*tmp);
    printf("after push *t2\r\n \r\n");

    Test1 tmp2 = *tmp;
    vec.push_back(tmp2);
    printf("\r\n to push NULL\n");
    //Test1 * tmpNull = NULL;
    //vec.push_back(*tmpNull);

    //printf("\r\n\r\n to print value. size=%zd\n", vec.size());
    //for(size_t i=0 ; i<vec.size(); ++i) {
    //    vec[i].PrintValue();
    //}
    //// 此选项打开后会，访问数据会引起程序崩溃

    printf("call Test1 & xx = *tmp  \n");
    Test1 &xx = *tmp;
    //Test1 & xx = t2;
    sleep(5);
}

int main()
{
    test_vector_copy();
    return 0;
    vector <int >a;
    cout<<a.empty()<<endl;//输出   1  代表该vector此时是空
    a.push_back(1);
    a.push_back(2);
    cout<<a[0]<<" "<<a[1]<<endl;//输出1 2
    cout<<a.empty()<<endl;//输出 0 代表该vector此时非空
    cout<<a.size()<<endl;//输出2
    cout<<a.capacity()<<endl;//输出2
    cout<<"***************"<<endl;

    //a[0]=NULL;a[1]=NULL; 这是赋值为0，并不清空数据，也不释放内存。也不释放内存
    a.clear();
    cout<<a[0]<<" "<<a[1]<<endl;//仍然输出1 2，因为没有释放内存，所以输出该地址的内容仍然与之前一样所以输出该地址的内容仍然与之前一样
    cout<<a.empty()<<endl;//输出1  代表该vector此时已经为空此时已经为空
    cout<<a.size()<<endl;//输出0，代表当前容器内存储元素个数是0，与.empty()类似，都告诉我们当前容器是空的意思都告诉我们当前容器是空的意思
    cout<<a.capacity()<<endl;//输出2，代表当前该vector在重新分配存储空间前所能容纳的元素数量并没有改变在重新分配存储空间前所能容纳的元素数量并没有改变
    cout<<"***************"<<endl;

    /*
       下面这五行说明，.pop_back()与.clear()起到了相同的作用，都是清空数据，但是没有释放内存
       while(!a.empty()){
       a.pop_back();
       }
       cout<<a.empty()<<endl;//输出 1 代表该vector此时已经为空
       cout<<a[0]<<" "<<a[1]<<endl;//仍然输出为 1 2，因为没有释放内存，所以输出该地址的内容仍然与之前一样
       */
    a.push_back(4);
    cout<<a[0]<<" "<<a[1]<<" "<<a[2]<<endl;//输出 4 2 0   尽管没有释放内存，但是已经认为该vector已经被清空，所以再push_back();时，a[0]被覆盖。
    cout<<a.size()<<endl;//输出1，代表当前容器内存储元素个数是1，就是刚刚push_back();装进去的数起到的作用
    cout<<a.capacity()<<endl;//此时仍然输出2
    cout<<"***************"<<endl;

    //那么如何释放内存呢？我们用swap交换到一个新的类型的vector,将原来的a拷贝出去，然后自然销毁，而新的到的a是全新的没有存任何数据的
    vector<int>().swap(a);
    //a.swap();
    cout<<a.size()<<endl;//输出 0
    cout<<a.capacity()<<endl;// 输出 0
        //cout<<a[1]<<endl;

}
